home *** CD-ROM | disk | FTP | other *** search
- Path: mail2news.demon.co.uk!genesis.demon.co.uk
- From: Lawrence Kirby <fred@genesis.demon.co.uk>
- Newsgroups: comp.lang.c
- Subject: Re: Q: gets, getch, and stdin
- Date: Wed, 06 Mar 96 22:28:27 GMT
- Organization: none
- Message-ID: <826151307snz@genesis.demon.co.uk>
- References: <DnoC9w.Eq9@info.uucp>
- Reply-To: fred@genesis.demon.co.uk
- X-NNTP-Posting-Host: genesis.demon.co.uk
- X-Newsreader: Demon Internet Simple News v1.27
- X-Mail2News-Path: genesis.demon.co.uk
-
- In article <DnoC9w.Eq9@info.uucp> rede4740@mach1.wlu.ca "Chris Redekop u" writes:
-
- >
- >Hi. I'm trying to teach myself C with the help of 'Teach Yourself C In
- >21 Days'. Everything was going fine until day 14, 'Working with the
- >Screen, Printer, and Keyboard'.
-
- Are you aware that Screen, Printer, and Keyboard are not things that the
- C language supports. All it knows about are files and 'streams' which you
- can open to files to read and write data. stdin, stdout and stderr are
- examples of streams that are opened for you when the program starts.
- Your particular system can contrive to attach Screen etc. to streams
- effectively simulating files but knowing this may help you understand how the
- I/O works.
-
- > On page 319 (in case anyone reading this
- >has the book), it talked about how using scanf can leave unwanted
- >characters in stdin. It offered this function as a way to clear stdin:
-
- The facilities that scanf provides simply doesn't make it particularly
- suitable for line based input - it doesn't treat '\n' specially, just like
- any other white-space.
-
- >void clear_kb(void)
- >{
- >char junk[80];
- >gets(junk);
- >}
-
- This is evil - gets() is historical baggage that you should never use.
- The problem is that you can't tell it the size of the buffer you passed it
- so if it encounters a line that is longer than the buffer it will overwrite
- the end of it and corrupt anything that happens to be there.
-
- >
- >I thought to myself, 'That might work, but it uses a whole array to do
- >it. Instead of clearing stdin by reading a whole string, I should be
- >able to clear it one chartacter at a time, by using getch(). Then I
- >would only need one local variable of type char (or int).' So I tried this:
-
- getch() is not a standard C function so its behaviour is not well defined
- and could vary from implementation to implementation. That happens in
- practice: under Unix getch() is part of the Curses library and works
- differently in relation to other functions that does the version you
- typically find under DOS. If your book didn't make it clear that getch()
- is non-standard that's the 2nd (or is that the 3rd?) black mark.
-
- >void clear_kb(void)
- >{
- >char ch;
- >
- >while ((ch = getch()) != '\r')
- > ;
- >}
- >
- >This didn't work, so after I tried a few different things, I found that
- >this works:
- >
- >void clear_kb(void)
- >{
- >char ch;
- >
- >while ((ch = getchar()) != '\n')
- > ;
- >}
-
- getchar() is a standard C library function however it returns int. There
- is a good reason for this because as well as any valid character (which
- is returned as a positive value) it can return EOF (which is a negative
- value) which is distinct from any valid character. It is important to test
- for EOF since you don't necessarily know where your input is coming from
- (e.g. stdin may have been redirected to a file by whatever ran your
- program).
-
- >This is what confuses me. I can't understand why the third function
- >works, and not the second. As well, the third function does not output
- >the cleared characters to the screen, even though getchar provides input
- >with echo.
-
- I couldn't say what getch() does because it is not well defined.
-
- getchar() is not defined to produce any sort of echo. However it, as well
- as any other standard function reading characters from an input stream,
- must get characters from the OS. In the case of stdin this is usually
- connected to the keyboard when the program starts. The OS will typically
- arrange to perform some rudimentary command line editing before making
- the complete line available to the program, e.g. when you press <return>.
- That line editing may well involve echoing characters to the screen but
- all of this is performed before the line is passed to the C program.
- The C library in general and getchar() in particular performs no echoing.
-
- The correct way to approach line based input is to read the line as a whole
- into a buffer using fgets(). fgets() allows you to specify the size of
- the buffer you pass it so doesn't suffer the same defect as gets(). Also
- remember it leaves the trailing '\n' at the end of the string. Once you
- have the line in the buffer you can pick it apart with your own code or
- a range of standard library functions e.g. atoi(), strtol(), sscanf(),
- strtok() etc.
-
- I suggest you look through the FAQ which provides much information
- in these areas. You can ftp it from rtfm.mit.edu under
- /pub/usenet/comp.lang.c.
-
- --
- -----------------------------------------
- Lawrence Kirby | fred@genesis.demon.co.uk
- Wilts, England | 70734.126@compuserve.com
- -----------------------------------------
-